package com.dsl.dslallinone.service;

import com.dsl.dslallinone.dto.DslQuery;
import com.dsl.dslallinone.dto.DslQueryResponse;
import com.dsl.dslallinone.dto.ExportResult;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * 导出服务
 */
@Service
public class ExportService {
    private static final Logger logger = LoggerFactory.getLogger(ExportService.class);

    @Autowired
    private DslQueryService dslQueryService;

    @Value("${dsl.query.export.max-sync-rows:100000}")
    private int maxSyncRows;

    @Value("${dsl.query.export.temp-dir:/tmp/dsl-export}")
    private String tempDir;

    /**
     * 导出CSV
     */
    public ExportResult exportToCsv(DslQuery query) {
        logger.info("开始导出CSV，最大行数限制: {}", maxSyncRows);

        try {
            // 执行查询
            DslQueryResponse response = dslQueryService.executeQuery(query);
            
            // 检查行数限制
            if (response.getTable().getRows().size() > maxSyncRows) {
                return ExportResult.error("数据量过大（>" + maxSyncRows + "行），请缩小查询范围");
            }

            // 创建临时文件
            File tempFile = createTempFile("csv");
            
            // 写入CSV
            try (FileWriter writer = new FileWriter(tempFile);
                 CSVPrinter printer = new CSVPrinter(writer, CSVFormat.DEFAULT.withHeader(
                         response.getTable().getColumns().toArray(new String[0])))) {
                
                for (List<Object> row : response.getTable().getRows()) {
                    printer.printRecord(row);
                }
            }

            String fileName = generateFileName("csv");
            return ExportResult.success(fileName, new FileSystemResource(tempFile));

        } catch (Exception e) {
            logger.error("CSV导出失败", e);
            return ExportResult.error("导出失败: " + e.getMessage());
        }
    }

    /**
     * 导出Excel
     */
    public ExportResult exportToXlsx(DslQuery query) {
        logger.info("开始导出Excel，最大行数限制: {}", maxSyncRows);

        try {
            // 执行查询
            DslQueryResponse response = dslQueryService.executeQuery(query);
            
            // 检查行数限制
            if (response.getTable().getRows().size() > maxSyncRows) {
                return ExportResult.error("数据量过大（>" + maxSyncRows + "行），请缩小查询范围");
            }

            // 创建临时文件
            File tempFile = createTempFile("xlsx");
            
            // 使用SXSSF写入Excel（流式处理，内存友好）
            try (Workbook workbook = new SXSSFWorkbook(1000); // 内存中保留1000行
                 FileOutputStream fos = new FileOutputStream(tempFile)) {
                
                Sheet sheet = workbook.createSheet("数据");
                
                // 写入表头
                Row headerRow = sheet.createRow(0);
                List<String> columns = response.getTable().getColumns();
                for (int i = 0; i < columns.size(); i++) {
                    headerRow.createCell(i).setCellValue(columns.get(i));
                }
                
                // 写入数据行
                List<List<Object>> rows = response.getTable().getRows();
                for (int i = 0; i < rows.size(); i++) {
                    Row dataRow = sheet.createRow(i + 1);
                    List<Object> rowData = rows.get(i);
                    for (int j = 0; j < rowData.size(); j++) {
                        Object value = rowData.get(j);
                        if (value != null) {
                            dataRow.createCell(j).setCellValue(value.toString());
                        }
                    }
                }
                
                workbook.write(fos);
            }

            String fileName = generateFileName("xlsx");
            return ExportResult.success(fileName, new FileSystemResource(tempFile));

        } catch (Exception e) {
            logger.error("Excel导出失败", e);
            return ExportResult.error("导出失败: " + e.getMessage());
        }
    }

    /**
     * 创建临时文件
     */
    private File createTempFile(String extension) throws IOException {
        File tempDirFile = new File(tempDir);
        if (!tempDirFile.exists()) {
            tempDirFile.mkdirs();
        }
        
        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss"));
        return File.createTempFile("dsl_export_" + timestamp + "_", "." + extension, tempDirFile);
    }

    /**
     * 生成文件名
     */
    private String generateFileName(String extension) {
        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss"));
        return "dsl_export_" + timestamp + "." + extension;
    }
}
